#include <iostream>
#include <string>
#include <unistd.h>
#include <signal.h>
#include <vector>
#include "MultiPlayerChatRoom.hpp"
#include "MySock.hpp"


int main()
{
    std::string serverIp = "43.143.4.250";
    uint16_t serverPort = 8080;

    int clientSock = QiHai::MySock::Socket();
    // 建立连接
    if (QiHai::MySock::Connect(clientSock, serverIp, serverPort))
        std::cout << "建立连接成功，现在开始聊天吧~\n";
    else
    {
        std::cout << "建立连接失败，请检查网络或者服务器问题，请重试\n";
        exit(1);
    }
    
    signal(SIGCHLD, SIG_IGN);  // 设置子进程结束信号应用层忽略，不会产生僵尸进程
    // 创建子进程，循环接收信息
    if (fork() == 0)
    {
        // 子进程
        char buffer[10240];
        std::string readBuffer;
        std::vector<std::string> _v;
        while(true)
        {
            ssize_t n = read(clientSock, buffer, 10240 -1);
            if (n > 0)
            {
                buffer[n] = '\0';
                readBuffer += buffer;
                QiHai::SpliteMessage(readBuffer, _v);

                for (auto& str : _v)
                {
                    QiHai::Respond res;
                    res.DeSerialization(str);
                    if (res._level == 0) std::cout << "[" <<  res._userName << "]: " << res._message << "\n";
                    else std::cout << "|系统消息：" << res._message << "|\n";
                }
                _v.clear();  // 清空
            }
            else
            {
                // 出错或者服务器关闭
                std::cout << "读取出错或者服务器关闭~" << std::endl;
                close(clientSock);
                break;
            }
        }
        exit(0);
    }

    // 循环发送信息
    std::string mess;
    while (true)
    {
        std::getline(std::cin, mess);
        if (mess == "#quit")
        {
            std::cout << "欢迎下次使用！\n";
            break;
        }
        // 构建请求
        QiHai::Request req(mess);
        std::string temp = req.Serialization();
        ssize_t n = write(clientSock, temp.c_str(), temp.size());
        if (n < 0)
        {
            std::cout << "发送失败！未知错误，终止程序\n";
            break;
        }
    }

    return 0;
}